import base64
import re
from time import sleep

import cv2
import ddddocr
import numpy as np
import requests
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait  # 这个是为显隐式等待提供方法的模块
from selenium.webdriver.support import expected_conditions as EC  # 这个是为显示等待提供定位功能的模块
from skimage.metrics import structural_similarity

options = webdriver.ChromeOptions()  # 创建谷歌浏览器的options对象来接收浏览器的相关设置

options.add_argument('--start-maximized')  # 最大化窗口
options.add_argument('--incognito')  # 无痕浏览
options.add_argument('--disable-extensions')  # 禁用浏览器的扩展程序,避免干扰网站的打开
options.add_experimental_option("detach", True)  # 禁止浏览器自动关闭
options.add_experimental_option('excludeSwitches', ['enable-automation'])
options.add_experimental_option('useAutomationExtension', False)

# options.add_argument('--headless')
# options.add_argument('user-agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36"')
# options.add_argument('--disable-gpu')

driver = webdriver.Chrome(options)  # 创建谷歌浏览器驱动对象
det = ddddocr.DdddOcr(det=True, show_ad=False)
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
    'source': '''
    Object.defineProperty(navigator, 'webdriver',{get:() => false})
    '''
})

driver.get('https://captcha2.scrape.center/')

wait = WebDriverWait(driver, 6)  # # 设置等待时间

# titles = driver.find_elements(By.CLASS_NAME, 'm-b-sm')
# titles = wait.until(EC.presence_of_all_elements_located((By.CLASS_NAME, 'm-b-sm')))

username_inp, password_inp = wait.until(
    EC.presence_of_all_elements_located((By.CLASS_NAME, 'el-input__inner'))
)

username_inp.send_keys('admin')
password_inp.send_keys('admin')

wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.el-button.el-button--primary'))).click()

while True:
    bg_url = wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'geetest_item_wrap'))).get_attribute('style')
    bg_url = re.findall(r'url\("(.*?)"\)', bg_url)[0]
    print(bg_url)
    bg_res = requests.get(bg_url)

    bg_img = wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'geetest_item_img')))
    bg_width = bg_img.rect['width']
    bg_height = bg_img.rect['height']

    bboxes = det.detection(bg_res.content)  # 找到图片中需要点击的坐标，目标检测
    print(bboxes)  # [[15, 47, 84, 117], [23, 165, 89, 234], [0, 345, 45, 383], [21, 344, 54, 381]]

    # cv2.imdecode(np.frombuffer(图片字节数据, np.uint8), cv2.IMREAD_COLOR) opencv加载图片
    im = cv2.imdecode(np.frombuffer(bg_res.content, np.uint8), cv2.IMREAD_COLOR)

    clicks_data = []  # 题目目标，要点击内容 [[坐标,图片数据],[]]
    ans_data = []  # 答案
    for bbox in bboxes:
        # 得到每个可能是目标的矩形范围
        x1, y1, x2, y2 = bbox  # 1左上角，2右下角

        img_data = im[y1:y2 + 1, x1:x2 + 1]  # 切割出目标图
        if y1 < 340:
            clicks_data.append([bbox, img_data])
        else:
            ans_data.append([bbox, img_data])

    ans_data.sort(key=lambda x: x[0][0])  # 制定点击顺序  [[坐标,图片数据],[]]
    for ans_bbox, ans in ans_data:
        max_ssim = 0
        max_bbox = None
        max_i = 0
        i = 0
        # 分别得到每个答案图片
        ans = cv2.cvtColor(ans, cv2.COLOR_RGB2GRAY)  # 转为灰度图
        for click_bbox, click_img in clicks_data:
            # 分别得到每个题目选项，与答案进行对比，结构相似性
            click_img = cv2.cvtColor(click_img, cv2.COLOR_RGB2GRAY)  # 转为灰度图

            h, w = click_img.shape  # 得到点击图像的尺寸
            ans = cv2.resize(ans, (w, h))  # 对答案图像进行缩放变成和选项图像一样的尺寸

            # h, w = ans.shape  # 得到点击图像的尺寸
            # click_img = cv2.resize(click_img, (w, h))  # 对答案图像进行缩放变成和选项图像一样的尺寸

            # print(ans.shape, click_img.shape)

            ssim = structural_similarity(click_img, ans, channel_axis=1)
            print(ans_bbox, click_bbox)
            print('ssim', ssim)

            if ssim > max_ssim:
                max_ssim = ssim
                max_bbox = click_bbox
                max_i = i
            i += 1

        clicks_data.pop(max_i)
        print('点击', max_ssim, max_bbox)
        mouse = webdriver.ActionChains(driver)
        mouse.move_to_element_with_offset(
            bg_img, max_bbox[0] + 20 - bg_width / 2, max_bbox[1] + 20 - bg_height / 2
        ).click().perform()
        sleep(1)

    # geetest_commit 点击确认按钮
    wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'geetest_commit'))).click()
    sleep(2)

    is_success = re.findall(r'登录成功', driver.page_source)
    if is_success:
        print(is_success)
        break
    else:
        print('登录失败')
        sleep(3)
input()
driver.quit()